﻿Namespace Models
    Public Class ShoppingCart

        Private storeDB As MusicStoreEntities = New MusicStoreEntities
        Property ShoppingCartId As String
        Public Const CartSessionKey = "CartId"

        Public Shared Function GetCart(ByVal context As HttpContextBase) As ShoppingCart
            Dim cart = New ShoppingCart
            cart.ShoppingCartId = cart.GetCartId(context)
            Return cart
        End Function

        ''' <summary>
        ''' Helper method to simplify shopping cart calls
        ''' </summary>
        Public Shared Function GetCart(ByVal controller As Controller) As ShoppingCart
            Return GetCart(controller.HttpContext)
        End Function

        Public Sub AddToCart(ByVal album As Album)
            'Get the matching cart and album instances
            Dim cartItem = storeDB.Carts.SingleOrDefault(Function(c) c.CartId = ShoppingCartId AndAlso c.AlbumId = album.AlbumId)

            If cartItem Is Nothing Then
                'Create a new cart item if no cart item exists
                cartItem = New Cart With {
                    .AlbumId = album.AlbumId,
                    .CartId = ShoppingCartId,
                    .Count = 1,
                    .DateCreated = DateTime.Now
                }
                storeDB.Carts.Add(cartItem)
            Else
                'If the item does exist in the cart, then add one to the quantity
                cartItem.Count += 1
            End If

            storeDB.SaveChanges()
        End Sub

        Public Function RemoveFromCart(ByVal id As Integer) As Integer
            'Get the cart
            Dim cartItem = storeDB.Carts.SingleOrDefault(Function(c) c.CartId = ShoppingCartId AndAlso c.RecordId = id)

            Dim itemCount = 0

            If cartItem IsNot Nothing Then
                If cartItem.Count > 1 Then
                    cartItem.Count -= 1
                    itemCount = cartItem.Count
                Else
                    storeDB.Carts.Remove(cartItem)
                End If
                storeDB.SaveChanges()
            End If

            Return itemCount
        End Function

        Public Sub EmptyCart()
            Dim cartItems = GetCartItems()

            For Each cartItem In cartItems
                storeDB.Carts.Remove(cartItem)
            Next

            storeDB.SaveChanges()
        End Sub

        Public Function GetCartItems() As List(Of Cart)
            Return (From cart In storeDB.Carts
                    Where cart.CartId = ShoppingCartId).ToList
        End Function

        Public Function GetCount() As Integer
            Dim count = (From cartItem In storeDB.Carts
                         Where cartItem.CartId = ShoppingCartId
                         Select itemCount = CType(cartItem.Count, Integer?)).Sum

            Return IIf(count.HasValue, count, 0)
        End Function

        Public Function GetTotal() As Decimal
            Dim total = (From cartItem In storeDB.Carts
                         Where cartItem.CartId = ShoppingCartId
                         Select CType(cartItem.Count * cartItem.Album.Price, Decimal?)).Sum

            Return IIf(total.HasValue, total, Decimal.Zero)
        End Function

        Public Function CreateOrder(ByVal order As Order) As Integer
            Dim orderTotal As Decimal = 0

            Dim cartItems = GetCartItems()

            For Each item In cartItems
                Dim orderDetail = New OrderDetail With {
                    .AlbumId = item.AlbumId,
                    .OrderId = order.OrderId,
                    .UnitPrice = item.Album.Price,
                    .Quantity = item.Count
                }
                orderTotal += item.Count * item.Album.Price

                storeDB.OrderDetails.Add(orderDetail)
            Next

            order.Total = orderTotal

            storeDB.SaveChanges()

            EmptyCart()

            Return order.OrderId
        End Function

        Public Function GetCartId(ByVal context As HttpContextBase) As String
            If context.Session(CartSessionKey) Is Nothing Then
                If Not String.IsNullOrWhiteSpace(context.User.Identity.Name) Then
                    context.Session(CartSessionKey) = context.User.Identity.Name
                Else
                    context.Session(CartSessionKey) = Guid.NewGuid.ToString
                End If
            End If

            Return context.Session(CartSessionKey).ToString
        End Function

        ''' <summary>
        ''' When a user has logged in, migrate thier shopping cart to 
        ''' be associated with their username
        ''' </summary>
        Public Sub MigrateCart(ByVal userName As String)
            Dim shoppingCart = GetCartItems()

            For Each item In shoppingCart
                item.CartId = username
            Next
            storeDB.SaveChanges()
        End Sub

    End Class
End Namespace